package com.unionServer.models;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;

/**
 * @description:
 * @author: wangxinal
 * @time: 2022/1/13 13:44
 */
@Slf4j
public class UnionDecodeMessage {

    @Getter
    private MessageHead messageHead ;

    @Getter
    private String messageTypeId ;

    @Getter
    private MessageBody messageBody ;

    public UnionDecodeMessage(byte[] msgs) throws Exception {
        //报文头
        int headLength = 46;
        byte[] headBytes = new byte[headLength];
        //报文类型标识符
        byte[] messageTypeBytes = new byte[4];

        BufferedInputStream in = null;
        in = new BufferedInputStream(new ByteArrayInputStream(msgs));
        try {
            in.read(headBytes);
            in.read(messageTypeBytes);
        } catch (IOException e) {
            throw new IOException("按照长度划分报文体失败" + e.getMessage());
        }
        String headStr = new String(headBytes, StandardCharsets.US_ASCII) ;
        log.info("head String is " +headStr);
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/main/resources/CUP_service_parse_default.xml"));

        Element rootElm = document.getRootElement();
        //解析报文头
        Element headElm = rootElm.element("fixmap").element("CUP_HEAD");
        messageHead = new MessageHead(headBytes,headElm);
        messageHead.toString();
        //解析报文类型标识符
        messageTypeId = new String (messageTypeBytes,StandardCharsets.US_ASCII);
        log.info("报文类型标识符 is "+ messageTypeId);
        //解析位图
        int bitMapLength = 8;
        byte[] bitMapBytes = new byte[bitMapLength];

        in.read(bitMapBytes);

        //第一位图
        String bitMapStr = getBitMap(bitMapBytes);
        //第二位图
        if (bitMapStr.startsWith("1") ){
            in.read(bitMapBytes);
            bitMapStr = bitMapStr + getBitMap(bitMapBytes);
        }
        log.info("bitMapStr is "+ bitMapStr);

        //报文体
        int bodyLength = msgs.length - headLength - bitMapLength ;
        byte[] bodyBytes = new byte[bodyLength];
        in.read(bodyBytes);

        Element bodyElm = rootElm.element("fixmap").element("BH_8583_BITMAP");
        messageBody = new MessageBody(bodyBytes,bitMapStr,bodyElm,messageTypeId);
    }

    public String byteArr2HexStr(byte[] arrB)
            throws IOException
    {
        int iLen = arrB.length;

        StringBuffer sb = new StringBuffer(iLen * 2);

        for (int i = 0; i < iLen; ++i)
        {
            int intTmp = arrB[i];

            while (intTmp < 0)
            {
                intTmp += 256;
            }

            if (intTmp < 16)
            {
                sb.append("0");
            }

            sb.append(Integer.toString(intTmp, 16));
        }

        return sb.toString();
    }
    private String getBitMap(byte[] bitmap) throws IOException {
        int i = 1;
        String temp = "00000000";
        String str = "";
        str = byteArr2HexStr(bitmap);
        log.info("bitmap hex:" + str);

        StringBuffer bitMapString = new StringBuffer();

        for(int j = 0; j < str.length(); ++j) {
            String t = Integer.toBinaryString(Integer.parseInt(str.substring(j, j + 1), 16));
            if (t.length() < 4) {
                t = temp.substring(0, 4 - t.length()) + t;
            }

            bitMapString.append(t);
            if (log.isDebugEnabled()) {
                log.debug(String.format("bit_map[%5d-%5d]\t%4s", (i - 1) * 4 + 1, i * 4, t));
            }

            ++i;
        }

        return bitMapString.toString();
    }
}
